@file:Suppress("unused", "UNUSED_VARIABLE")

package com.rzico.sbl.other

import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.rzico.sbl.R
import com.xinnuo.common.extend.getColorEx
import com.xinnuo.common.helper.dp2px


class ManagerDecoration
@JvmOverloads
constructor(
    horizontal: Int = 0,
    vertical: Int = 0
) : RecyclerView.ItemDecoration() {

    private var gapSizeHorizontal = dp2px(horizontal.toFloat())
    private var gapSizeVertical = dp2px(vertical.toFloat())

    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(c, parent, state)
        when (parent.layoutManager) {
            is GridLayoutManager -> {
                val manager = parent.layoutManager as GridLayoutManager
                val itemCount = manager.itemCount       //item总数
                val spanCount = manager.spanCount       //列数
                val sizeLookup = manager.spanSizeLookup //item所占列数管理类

                for (i in 0 until parent.childCount) {
                    val view: View = parent.getChildAt(i)
                    val position = parent.getChildLayoutPosition(view)
                    val adapterPostion = parent.getChildAdapterPosition(view)
                    val spanSize = sizeLookup.getSpanSize(adapterPostion)

                    if (spanCount > 0) {
                        if (spanCount > spanSize) {
                            val beforeFullSpanCountPos =
                                getBeforeFullSpanCountPostion(sizeLookup, spanCount, adapterPostion)

                            //检查是否位于网格中的第一行
                            val isFristRow =
                                isFristGridRow(spanCount, position, beforeFullSpanCountPos)

                            if (!isFristRow) {
                                c.drawRect(
                                    view.left.toFloat(),
                                    (view.top - gapSizeVertical).toFloat(),
                                    view.right.toFloat(),
                                    view.top.toFloat(),
                                    Paint().apply {
                                        isAntiAlias = true
                                        color = parent.context.getColorEx(R.color.white)
                                    })
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * @param outRect 全为0的rect，用来指定偏移区域
     * @param view    指RecyclerView中的Item
     * @param parent  指RecyclerView本身
     * @param state   状态
     */
    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        super.getItemOffsets(outRect, view, parent, state)
        val position = parent.getChildLayoutPosition(view)
        val adapterPostion = parent.getChildAdapterPosition(view)

        when (parent.layoutManager) {
            is GridLayoutManager -> {
                val manager = parent.layoutManager as GridLayoutManager
                val itemCount = manager.itemCount                     //item总数
                val spanCount = manager.spanCount                     //列数
                val sizeLookup = manager.spanSizeLookup               //item所占列数管理类
                val spanSize = sizeLookup.getSpanSize(adapterPostion) //当前item所占列数

                if (spanCount > 0) {
                    if (spanSize == spanCount) {
                        // item占满一行，不做偏移处理
                        outRect.set(0, 0, 0, 0)
                    } else {
                        val beforeFullSpanCountPos =
                            getBeforeFullSpanCountPostion(sizeLookup, spanCount, adapterPostion)

                        // 检查是否位于网格中的第一行
                        val isFristRow = isFristGridRow(spanCount, position, beforeFullSpanCountPos)

                        // 检查是否允许网格中的第一行元素的marginTop是否允许设置值 -true标识允许
                        val top = if (isFristRow) 0 else gapSizeVertical

                        outRect.top = top
                    }
                }
            }
            else -> throw IllegalAccessError("暂只支持Grid布局")
        }
    }

    /**
     * 寻找上方最近一个占据spanCount整列的位置
     */
    private fun getBeforeFullSpanCountPostion(
        sizeLookup: GridLayoutManager.SpanSizeLookup,
        spanCount: Int,
        adapterPostion: Int
    ): Int {
        (adapterPostion downTo 0).forEach {
            if (sizeLookup.getSpanSize(it) == spanCount) return it
        }
        return -1
    }

    /**
     * 寻找下方最近一个占据spanCount整列的位置
     */
    private fun getLastFullSpanCountPostion(
        sizeLookup: GridLayoutManager.SpanSizeLookup,
        spanCount: Int,
        itemCount: Int,
        adapterPostion: Int
    ): Int {
        (adapterPostion until itemCount).forEach {
            if (sizeLookup.getSpanSize(it) == spanCount) return it
        }
        return -1
    }

    /**
     * 是否为最后一列数据
     */
    private fun isLastGridCol(
        spanCount: Int,
        position: Int,
        lastFullSpanPosition: Int
    ) = (position - lastFullSpanPosition) % spanCount == 0

    /**
     * 是否为第一行数据到上方最近一个占据spanCount整列
     */
    private fun isFristGridRow(
        spanCount: Int,
        position: Int,
        lastFullSpanPosition: Int
    ) = position - lastFullSpanPosition <= spanCount

    /**
     * 是否为全部数据的最后一行
     */
    private fun isLastGridRow(
        spanCount: Int,
        position: Int,
        itemCount: Int
    ) = itemCount - position <= spanCount

}
